package com.ccb.sc.luxury.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ccb.sc.constant.OrderConstant;
import com.ccb.sc.luxury.convert.AppLuxuryConvert;
import com.ccb.sc.luxury.query.AppLuxurySearchParam;
import com.ccb.sc.luxury.vo.*;
//psl import com.ccb.sc.common.bind.exception.BizException;
import com.ccb.sc.common.bind.page.PageVo;
import com.ccb.sc.common.code.BizCodeFace;
import com.ccb.sc.common.code.ErrorCode;
import com.ccb.sc.common.modules.common.service.IRedisService;
import com.ccb.sc.common.modules.luxury.entity.LuxuryLogistics;
import com.ccb.sc.common.modules.luxury.entity.LuxuryOrder;
import com.ccb.sc.common.modules.luxury.enums.AcceptWay;
import com.ccb.sc.common.modules.luxury.enums.LuxuryLogisticsType;
import com.ccb.sc.common.modules.luxury.enums.LuxuryStatus;
import com.ccb.sc.common.modules.luxury.mapper.LuxuryOrderMapper;
import com.ccb.sc.common.modules.luxury.service.LuxuryLogisticsService;
import com.ccb.sc.common.modules.luxury.vo.LuxuryLogisticsVo;
import com.ccb.sc.common.modules.member.enums.MemberPointsLogType;
import com.ccb.sc.common.modules.member.enums.MemberStatus;
import com.ccb.sc.common.modules.member.service.MemberPointsService;
import com.ccb.sc.common.modules.setting.service.ISettingsService;
import com.ccb.sc.common.modules.setting.vo.OrderSettingsVo;
import com.ccb.sc.common.modules.shopkeeper.entity.Shopkeeper;
import com.ccb.sc.common.modules.shopkeeper.enums.ShopkeeperLevel;
import com.ccb.sc.common.modules.shopkeeper.enums.ShopkeeperPointsLogType;
import com.ccb.sc.common.modules.shopkeeper.service.ShopkeeperPointsLogService;
import com.ccb.sc.common.modules.shopkeeper.service.ShopkeeperService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author ken
 * @version 1.0
 * @date 2025/2/23 14:46
 */
@Slf4j
@Service
public class AppLuxuryService extends ServiceImpl<LuxuryOrderMapper, LuxuryOrder> {

    @Autowired
    private IRedisService redisService;

    @Autowired
    private LuxuryLogisticsService logisticsService;

    @Autowired
    private ShopkeeperPointsLogService shopkeeperPointsLogService;

    @Autowired
    private ShopkeeperService shopkeeperService;

    @Autowired
    private MemberPointsService memberPointsService;

    @Autowired
    private ISettingsService settingsService;

    public PageVo<LuxuryListVo> list(Long memberId, AppLuxurySearchParam queryParam) {
        Page<LuxuryOrder> page = new Page<>(queryParam.getCurrent(), queryParam.getPageSize());
        LambdaQueryWrapper<LuxuryOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LuxuryOrder::getMemberId, memberId);
        if (queryParam.getStatus() != null) {
            if (queryParam.getStatus() == 1) {
                queryWrapper.in(LuxuryOrder::getStatus, Lists.newArrayList(LuxuryStatus.APPLY, LuxuryStatus.ASSESS, LuxuryStatus.EXPRESS,
                        LuxuryStatus.ACCEPTANCE_CHECK));
            }else if (queryParam.getStatus() == 2) {
                queryWrapper.in(LuxuryOrder::getStatus, Lists.newArrayList(LuxuryStatus.FAIL, LuxuryStatus.FINISHED));
            }else {
                queryWrapper.eq(LuxuryOrder::getStatus, null);
            }
        }
        queryWrapper.eq(LuxuryOrder::getMemberId, memberId);
        queryWrapper.orderByDesc(LuxuryOrder::getCreateTime);
        Page<LuxuryOrder> luxuryOrderPage = this.page(page, queryWrapper);
        List<LuxuryOrder> records = luxuryOrderPage.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return PageVo.create(queryParam.getCurrent(), queryParam.getPageSize(), 0, Lists.newArrayList());
        }
        List<LuxuryListVo> luxuryList = AppLuxuryConvert.INSTANCE.entity2Vo(records);
        return PageVo.create(queryParam.getCurrent(), queryParam.getPageSize(), luxuryOrderPage.getTotal(), luxuryList);
    }

    public LuxuryDetailVo detail(Long memberId, String orderId) {
        LuxuryOrder luxuryOrder = this.getById(orderId);
        if (luxuryOrder == null || !Objects.equals(memberId, luxuryOrder.getMemberId())) {
            return null;
        }
        LuxuryDetailVo detailVo = AppLuxuryConvert.INSTANCE.entity2Vo(luxuryOrder);
        List<LuxuryLogistics> luxuryLogistics = logisticsService.findByOrderId(orderId);
        List<LuxuryLogisticsVo> logisticsVos = AppLuxuryConvert.INSTANCE.logistics2Vo(luxuryLogistics);
        detailVo.setLuxuryLogisticsList(logisticsVos);
        return detailVo;
    }


    public void apply(Long memberId, LuxuryApplyVo applyVo) {
        LuxuryOrder luxuryOrder = new LuxuryOrder();
        String orderId = this.redisService.getNextStandardCodeByDayClean(OrderConstant.ORDER_LUXURY_KEY, 4);
        luxuryOrder.setId(orderId);
        luxuryOrder.setMemberId(memberId);
        luxuryOrder.setGoodsName(applyVo.getGoodsName());
        luxuryOrder.setDetail(applyVo.getDetail());
        luxuryOrder.setPictures(applyVo.getPictures());
        luxuryOrder.setAdditionalRemark(applyVo.getAdditionalRemark());
        luxuryOrder.setStatus(LuxuryStatus.APPLY);
        this.save(luxuryOrder);
    }


    public void post(Long memberId, LuxuryPostVo postVo) {
        LuxuryOrder luxuryOrder = this.getById(postVo.getId());
        Assert.notNull(luxuryOrder, "回收订单不存在！");
        if (Objects.equals(luxuryOrder.getStatus(), LuxuryStatus.APPLY)) {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.DATE_NULL).message("请待平台估价再邮寄"));
        }
        if (Objects.equals(luxuryOrder.getStatus(), LuxuryStatus.ASSESS)) {
            luxuryOrder.setStatus(LuxuryStatus.EXPRESS);
            this.updateById(luxuryOrder);

            OrderSettingsVo settings = this.settingsService.getSettings(OrderSettingsVo.class);
            LuxuryLogistics luxuryLogistics = new LuxuryLogistics();
            luxuryLogistics.setOrderId(postVo.getId());
            luxuryLogistics.setConsignee(settings.getAfterSaleConsignee());
            luxuryLogistics.setPhone(settings.getAfterSalePhone());
            luxuryLogistics.setAddress(settings.getAfterSaleAddress());
            luxuryLogistics.setLogisticsNo(postVo.getLogisticsNo());
            luxuryLogistics.setLogisticsCompany(postVo.getLogisticsCompany());
            luxuryLogistics.setType(LuxuryLogisticsType.DELIVERY);
            this.logisticsService.save(luxuryLogistics);
        }else if (Objects.equals(luxuryOrder.getStatus(), LuxuryStatus.EXPRESS)) {
            LuxuryLogistics luxuryLogistics = this.logisticsService.findByOrderIdAndType(postVo.getId(), LuxuryLogisticsType.DELIVERY);
            luxuryLogistics.setLogisticsNo(postVo.getLogisticsNo());
            luxuryLogistics.setLogisticsCompany(postVo.getLogisticsCompany());
            this.logisticsService.updateById(luxuryLogistics);
        }else {
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.DATE_NULL).message("已验收，无需邮寄"));
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void accept(Long memberId, LuxuryAcceptVo acceptVo) {
        String orderId = acceptVo.getId();
        LuxuryOrder luxuryOrder = this.getById(orderId);
        Assert.notNull(luxuryOrder, "回收订单不存在！");
        Assert.isTrue(Objects.equals(luxuryOrder.getStatus(), LuxuryStatus.ACCEPTANCE_CHECK), "请待平台验收后再接受");
        luxuryOrder.setIsAccept(Boolean.TRUE);
        luxuryOrder.setAcceptWay(AcceptWay.getByValue(acceptVo.getAcceptWay()));
        luxuryOrder.setStatus(LuxuryStatus.FINISHED);

        BigDecimal finalPrice = luxuryOrder.getFinalPrice();
        // 增加积分/余额
        if (Objects.equals(acceptVo.getAcceptWay(), AcceptWay.POINT.getValue())) {
            OrderSettingsVo settings = this.settingsService.getSettings(OrderSettingsVo.class);
            BigDecimal pointsExchangeAmount = Optional.ofNullable(settings.getPointsExchangeAmount()).orElse(new BigDecimal("0.1"));
            BigDecimal divide = finalPrice.divide(pointsExchangeAmount, 0, RoundingMode.HALF_UP);
            this.memberPointsService.award(memberId, divide.intValue(), MemberPointsLogType.LUXURY_RECYCLE, orderId);

            luxuryOrder.setFinalPrice(divide);
        }else if (Objects.equals(acceptVo.getAcceptWay(), AcceptWay.AMOUNT.getValue())) {
            Shopkeeper shopkeeper = this.shopkeeperService.findByMemberId(memberId);
            if (shopkeeper == null) {
                shopkeeper = new Shopkeeper();
                shopkeeper.setMemberId(memberId);
                shopkeeper.setPoints(BigDecimal.ZERO);
                shopkeeper.setTotalPoints(BigDecimal.ZERO);
                shopkeeper.setLevel(ShopkeeperLevel.ORDINARY_MEMBER);
                shopkeeper.setWechatNo("");
                shopkeeper.setAssistantWechatNo("");
                shopkeeper.setStatus(MemberStatus.AVAILABLE);
                this.shopkeeperService.save(shopkeeper);
            }
            this.shopkeeperPointsLogService.award(shopkeeper.getId(), finalPrice, ShopkeeperPointsLogType.LUXURY_RECYCLE, orderId, memberId);
        }else {
            log.error("回收方式数据异常：[{}]", acceptVo);
            //psl throw new BizException(BizCodeFace.createBizCode(ErrorCode.DATE_NULL).message("回收方式异常！"));
        }

        this.updateById(luxuryOrder);
    }

    @Transactional(rollbackFor = Exception.class)
    public void refuse(Long memberId, LuxuryRefuseVo refuseVo) {
        LuxuryOrder luxuryOrder = this.getById(refuseVo.getId());
        Assert.notNull(luxuryOrder, "回收订单不存在！");
        luxuryOrder.setIsAccept(Boolean.FALSE);
        luxuryOrder.setStatus(LuxuryStatus.FAIL);
        this.updateById(luxuryOrder);

        LuxuryLogistics luxuryLogistics = this.logisticsService.findByOrderIdAndType(refuseVo.getId(), LuxuryLogisticsType.RETURN_BACK);
        if (luxuryLogistics == null) {
            luxuryLogistics = new LuxuryLogistics();
            luxuryLogistics.setOrderId(refuseVo.getId());
            luxuryLogistics.setConsignee(refuseVo.getConsignee());
            luxuryLogistics.setPhone(refuseVo.getPhone());
            luxuryLogistics.setRegionId(refuseVo.getRegionId());
            luxuryLogistics.setAddress(refuseVo.getAddress());
            luxuryLogistics.setType(LuxuryLogisticsType.RETURN_BACK);
            this.logisticsService.save(luxuryLogistics);
        }else {
            luxuryLogistics.setConsignee(refuseVo.getConsignee());
            luxuryLogistics.setPhone(refuseVo.getPhone());
            luxuryLogistics.setRegionId(refuseVo.getRegionId());
            luxuryLogistics.setAddress(refuseVo.getAddress());
            this.logisticsService.updateById(luxuryLogistics);
        }

    }
}
